#define  _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>

using namespace std;

vector<string> split(const string& s, const string& sep)
{
	vector<string> ans;
	size_t i = 0, n = s.size();
	while (i < n)
	{
		size_t pos = s.find(sep, i);
		if (pos == string::npos)
		{
			ans.push_back(s.substr(i));
			break;
		}
		ans.push_back(s.substr(i, pos - i));
		i = pos;
		i += sep.size();
	}
	return ans;
}

string merge(const vector<string>& v, const string& sep)
{
	string ans;
	for (auto& s : v)
	{
		ans += s;
		ans += sep;
	}
	return ans;
}

bool isprime(int x)
{
	if (x < 2) return false;
	for (int i = 2; i <= x / i; i++)
	{
		if (x % i == 0) return false;
	}
	return true;
}

int max_prime(int n)
{
	for (int i = n; i >= 2; i--)
	{
		if (isprime(i)) return i;
	}
	return -1;
}

int same_number(const vector<int>& v)
{
	unordered_map<int, int> h;
	for (auto& e : v) if(++ h[e] == 2) return e;
	return -1;
}



int n;
vector<string> ans;
bool st[26];

void _dfs(int pos, string s)
{
	if (pos == n)
	{
		ans.push_back(s);
		return;
	}

	for (int i = 0; i < 26; i++)
	{
		st[i] = true;
		s += 'a' + i;
		_dfs(pos + 1, s);
		st[i] = false;
		s.pop_back();
	}
}

void dfs()
{
	for (int i = 1; i <= 26; i++)
	{
		n = i;
		ans.clear();
		memset(st, 0, sizeof st);

		string s;
		_dfs(0, s);
	}
}

int main()
{
	dfs();
	for (auto& s : ans) cout << s << endl;
	return 0;
}

//int soluation(int n, int m)
//{
//	vector<bool> st(n, true);
//	int count = n, begin = 0, t = 1;
//	while (count != 1)
//	{
//		while (t != m)
//		{
//			if (st[begin] == false)
//			{
//				begin++;
//				begin %= n;
//			}
//			begin++;
//			t++;
//			begin %= n;
//		}
//		st[begin] = false;
//		count--;
//		begin++;
//		begin %= n;
//		t = 1;
//	}
//	for (int i = 0; i < n; i++) if (st[i]) return i + 1;
//}
//
//int main()
//{
//	cout << soluation(3, 4) << endl;
//	return 0;
//}